package com.example.myfirstgame.controller;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Rect;

import com.example.myfirstgame.helper.Coordinate;
import com.example.myfirstgame.model.Car;
import com.example.myfirstgame.model.ParkingLot;
import com.example.myfirstgame.model.TrafficLight;
import com.example.myfirstgame.model.Tree;

public class CollisionListener {

	// ###############################
	// FIELDS
	// ###############################

	private static ArrayList<CollisionObject> mCollidables = new ArrayList<CollisionObject>();
	private static GameObjectContainer mGameObjectContainer = null;
	private static Context mContext = null;

	// ###############################
	// CONSTRUCTOR
	// ###############################

	public CollisionListener(Context _context) {
		mContext = _context;
	}

	// ###############################
	// GETTER & SETTER
	// ###############################

	public void addCollidable(CollisionObject collidable) {
		mCollidables.add(collidable);
	}

	public void addCollidable(CollisionObject[] _collidables) {
		for (CollisionObject co : _collidables) {
			mCollidables.add(co);
		}
	}

	public void removeCollidable(CollisionObject collidable) {
		mCollidables.remove(collidable);
	}

	public void bindToGameObjectContainer(
			GameObjectContainer pGameObjectContainer) {
		mGameObjectContainer = pGameObjectContainer;
	}

	// ###############################
	// Public Methods
	// ###############################

	public boolean checkCollisionState() {
		boolean ret = false;
		ArrayList<Rect> boundingBoxes = new ArrayList<Rect>();
		if (mGameObjectContainer != null) {
			mCollidables = mGameObjectContainer.deliverAllCollitionObjects();
		}
		for (CollisionObject c : mCollidables) {
			boundingBoxes.add(c.getBoundingRectangle());
		}

		for (int i = 0; i < boundingBoxes.size(); i++) {
			Rect a_box = boundingBoxes.get(i);
			Coordinate a_topLeft = new Coordinate(a_box.left, a_box.top);
			Coordinate a_bottomRight = new Coordinate(a_box.right, a_box.bottom);
			for (int j = i + 1; (j) < boundingBoxes.size(); j++) {
				Rect b_box = boundingBoxes.get(j);
				Coordinate b_topLeft = new Coordinate(b_box.left, b_box.top);
				Coordinate b_bottomRight = new Coordinate(b_box.right,
						b_box.bottom);
				if (a_topLeft.x >= b_bottomRight.x
						|| a_bottomRight.x <= b_topLeft.x
						|| a_topLeft.y >= b_bottomRight.y
						|| a_bottomRight.y <= b_topLeft.y) {
					ret = false;
					// Log.d("CollitionListener", "No Collition");
				} else {
					ret = true;
					onCollision(i, j);
					// Log.d("CollitionListener", "Collition");
				}
			}
		}
		return ret;
	}

	// ###############################
	// Inner Methods
	// ###############################

	private void onCollision(int id1, int id2) {
		// Object 1 is Car
		if (mCollidables.get(id1).getCollisonType()
				.equalsIgnoreCase(Car.TYPE_DEFINITION)) {
			// Object 2 is Car
			if (mCollidables.get(id2).getCollisonType()
					.equalsIgnoreCase(Car.TYPE_DEFINITION)) {

				Car car1 = (Car) mCollidables.get(id1);
				car1.stop();
			}
			// Object 2 is Tree
			else if (mCollidables.get(id2).getCollisonType()
					.equalsIgnoreCase(Tree.TYPE_DEFINITION)) {

				Car car1 = (Car) mCollidables.get(id1);
				car1.stop();
			}
			// Object 2 is Red TrafficLight
			else if (mCollidables
					.get(id2)
					.getCollisonType()
					.equalsIgnoreCase(
							TrafficLight.TYPE_DEFINITION[TrafficLight.RED])) {

				Car car1 = (Car) mCollidables.get(id1);
				car1.pause();
			}
			// Object 2 is Green TrafficLight
			else if (mCollidables
					.get(id2)
					.getCollisonType()
					.equalsIgnoreCase(
							TrafficLight.TYPE_DEFINITION[TrafficLight.GREEN])) {

				Car car1 = (Car) mCollidables.get(id1);
				car1.restart();
			}
			// Object 2 is ParkingLot
			else if (mCollidables.get(id2).getCollisonType()
					.equalsIgnoreCase(ParkingLot.TYPE_DEFINITION)) {

				Car car1 = (Car) mCollidables.get(id1);
				ParkingLot parkingLot2 = (ParkingLot) mCollidables.get(id2);

				if (parkingLot2.isEmptySpace()) {
					car1.parkOn(parkingLot2);
				} else {
					// do Nothing
				}

			}
		}
		// Object 2 is Car
		if (mCollidables.get(id2).getCollisonType()
				.equalsIgnoreCase(Car.TYPE_DEFINITION)) {
			// Object 1 is Car
			if (mCollidables.get(id1).getCollisonType()
					.equalsIgnoreCase(Car.TYPE_DEFINITION)) {

				Car car2 = (Car) mCollidables.get(id2);
				car2.stop();
			}
			// Object 1 is Tree
			else if (mCollidables.get(id1).getCollisonType()
					.equalsIgnoreCase(Tree.TYPE_DEFINITION)) {

				Car car2 = (Car) mCollidables.get(id2);
				car2.stop();
			}
			// Object 1 is Red TrafficLight
			else if (mCollidables
					.get(id1)
					.getCollisonType()
					.equalsIgnoreCase(
							TrafficLight.TYPE_DEFINITION[TrafficLight.RED])) {

				Car car2 = (Car) mCollidables.get(id2);
				car2.pause();
			}
			// Object 1 is Green TrafficLight
			else if (mCollidables
					.get(id1)
					.getCollisonType()
					.equalsIgnoreCase(
							TrafficLight.TYPE_DEFINITION[TrafficLight.GREEN])) {

				Car car2 = (Car) mCollidables.get(id2);
				car2.restart();
			}

			// Object 1 is ParkingLot
			else if (mCollidables.get(id1).getCollisonType()
					.equalsIgnoreCase(ParkingLot.TYPE_DEFINITION)) {

				Car car2 = (Car) mCollidables.get(id2);
				ParkingLot parkingLot1 = (ParkingLot) mCollidables.get(id1);

				if (parkingLot1.isEmptySpace()) {
					car2.parkOn(parkingLot1);
				} else {
					// do Nothing
				}

			}
		}
	}

}
